﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

#pragma once
#include <vector>
#include "IDock.h"
#include "GcmpGUiBaseInterface.h"
#include "OwnerPtr.h"

namespace gcmp
{
    class IDock;

    /// \brief 浮动面板管理器
    ///
    /// 负责管理各种浮动面板
    class GCMP_GUI_BASE_INTERFACE_EXPORT IDockManager
    {
    public:
        /// \brief 析构器
        virtual ~IDockManager();

    public:
        /// \brief 通过名字、标题创建一个浮动面板
        /// \return 浮动面板
        virtual OwnerPtr<IDock> CreateDock(const std::wstring& name, const std::wstring& title) const = 0;

        /// \brief 增加浮动面板
        /// \param opDock 浮动面板
        /// \param area 停靠位置
        /// \param orientation 停靠方向
        /// \return 无
        /// \see DockArea,DockOrientation
        virtual void AddDock(OwnerPtr<IDock> opDock, DockArea area, DockOrientation orientation) = 0;

        /// \brief 通过名字删除浮动面板
        /// \param name 浮动面板名字
        /// \return 无
        virtual void DeleteDock(const std::wstring& name) = 0;

        /// \brief 通过名字获取浮动面板
        /// \param name 浮动面板名字
        /// \return 浮动面板
        virtual IDock* GetDock(const std::wstring& name) = 0;

        /// \brief 根据一组尺寸和方向来调整一组浮动面板
        /// \param docks 一组浮动面板
        /// \param sizes 一组对应的尺寸
        /// \param orientation 调整方向，即调整面板的水平还是竖直方向的尺寸
        /// \return 无
        /// \see DockOrientation
        virtual void ResizeDocks(const std::vector<IDock*>& docks, const std::vector<int>& sizes, DockOrientation orientation) = 0;

        /// \brief 对浮动面板进行嵌套
        ///
        /// 此函数可以把第一个浮动面板（pFirstDock）在其位置上进行嵌套第二个浮动面板（pSecondDock），嵌套可以指定水平嵌套或者垂直嵌套(orientation)，
        /// 嵌套方向是从左到右，从上到下，也就是first相对于second永远在左边或者上边。
        /// \param pFirstDock 第一个浮动面板
        /// \param pSecondDock 第二个浮动面板
        /// \param orientation 嵌套方向，参见DockOrientation
        /// \return 无
        /// \see DockOrientation
        virtual void SplitDock(IDock *pFirstDock, IDock *pSecondDock, DockOrientation orientation) = 0;

        /// \brief 获取与目标浮动面板属于同一个Tab组的一组浮动面板
        /// \param pDock 目标浮动面板
        /// \return 无
        virtual std::vector<IDock*> TabifiedDocks(IDock* pDock) const = 0;

        /// \brief 对两个浮动面板实现Tab合并
        /// \param pFirstDock 第一个浮动面板
        /// \param pSecondDock 第二个浮动面板
        /// \return 无
        virtual void TabifyDock(IDock* firstDock, IDock* secondDock) = 0;  

        /// \brief 显示所有浮动面板
        /// \return 无
        virtual void ShowAllDockPane() = 0;

        /// \brief 隐藏所有浮动面板
        /// \return 无
        virtual void HideAllDockPane() = 0;

        /// \brief 面板是否可以Dockable，具体指是否可以关闭、移动和浮动停靠
        ///
        /// 该值所有面板初始为true，可以通过SetIsDockable()改动。
        /// \return bool true可以；false不可以。面板不存在返回false。
        virtual bool IsDockable(const std::wstring & name) const = 0;

        /// \brief 设置面板是否可以Dockable，具体指关闭、移动和浮动停靠
        /// \param name 面板名字
        /// \param isDockable 是否可以关闭、移动和浮动停靠
        /// \return bool 是否设置成功。面板不存在返回false。
        virtual bool SetIsDockable(const std::wstring & name, bool isDockable) = 0;

        /// \brief 移除面板上的标题栏
        ///  移除标题栏后，面板不可拖到，并且不能通过SetIsDockable使面板拖到
        /// \param name 面板名字
        /// \return bool 是否移除成功。面板不存在返回false。
        virtual bool RemoveDockTitleBar(const std::wstring & name) = 0;

        /// \brief 更新所有dock的状态，
        virtual void UpdateAllDockStatus() = 0;
    };
}
